package com.yu.mall.service;

import cn.hutool.core.date.StopWatch;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yu.mall.dto.ProductInfoDto;
import com.yu.mall.entity.ProductInfo;
import com.yu.mall.entity.ProductInfoExample;
import com.yu.mall.enums.StatusEnum;
import com.yu.mall.mapper.ProductInfoMapper;
import com.yu.mall.mapper.ext.ExtProductInfoMapper;
import com.yu.mall.runnable.ProductRunnable;
import com.yu.mall.util.JDUtils;
import com.yu.mall.util.ListSortUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @Desc:
 * @Author: zhangyicheng
 * @Date: 2021/3/4
 */
@Service
@Slf4j
public class ProductService {

    @Resource
    ProductInfoMapper productInfoMapper;
    @Resource
    ExtProductInfoMapper extProductInfoMapper;

    private final static ExecutorService PRODUCT_THREAD_POOL  = Executors.newFixedThreadPool(10);

    private static Map<String, String> allProductType = new HashMap<>();

    //获取所有商品分类
    public Map<String, String> getAllProductType() {
        if (allProductType.isEmpty()) {
            List<Map<String, String>> list = extProductInfoMapper.getAllProductType();
            allProductType = ListSortUtil.listToMap(list, "code", "name");
        }
        return allProductType;
    }

    //跑批拉取所有商品信息
    public void taskForGetAll1() {
        try {
        	log.info("1更新商品开始");
            StopWatch sw = new StopWatch();
            sw.start();
            Map<String, Object> map = JDUtils.productGetPageNum(null);
            if (map.isEmpty()) {
                log.error("1查询商品池编号失败");
                return;
            }
            //下架所有商品
            ProductInfo updateBean = new ProductInfo();
            updateBean.setIsdel("1");
            productInfoMapper.updateByExampleSelective(updateBean,new ProductInfoExample());
            //更新商品
            JSONArray data = (JSONArray) map.get("data");
            Map<String, String> typeMap = new HashMap<>();
            CountDownLatch countDownLatch = new CountDownLatch(data.size());
            log.info("countDownLatch之前"+ countDownLatch);
            for (int i = 0; i < data.size(); i++) {
                JSONObject brandItem = data.getJSONObject(i);
                String typeName = brandItem.getString("name");
                String typeCode = brandItem.getString("page_num");
                typeMap.put(typeCode, typeName);
                //getPrdListByType(typeCode,typeName);
                PRODUCT_THREAD_POOL.submit(new ProductRunnable(productInfoMapper,typeCode,typeName,countDownLatch));
            }
            allProductType.putAll(typeMap);
            countDownLatch.await();
            sw.stop();
            System.out.println("量获取商品列表耗时："+sw.getTotalTimeMillis());
            log.info("1批量获取商品列表，结束");
        } catch (Exception e) {
            log.error("1批量获取商品列表，出错", e);
        }
    }
    
    //分页查询商品
    public List<ProductInfo> pageQueryProduct(ProductInfoDto reqDto, int pageNum, int pageSize) {
        ProductInfoExample example = buildPageExmple(reqDto);
        example.setOffset((pageNum - 1l) * pageSize);
        example.setLimit(pageSize);
        example.setOrderByClause("create_datetime desc");
        if ("priceAsc".equals(reqDto.getOrderByType())) {
            example.setOrderByClause("jd_price asc");
        } else if ("priceDesc".equals(reqDto.getOrderByType())) {
            example.setOrderByClause("jd_price desc");
        } else if ("rateAsc".equals(reqDto.getOrderByType())) {
            example.setOrderByClause("rate asc");
        } else if ("rateDesc".equals(reqDto.getOrderByType())) {
            example.setOrderByClause("rate desc");
        }
        return productInfoMapper.selectByExample(example);
    }

    //分页查询总数
    public long pageQueryProductCount(ProductInfoDto reqDto) {
        ProductInfoExample example = buildPageExmple(reqDto);
        return productInfoMapper.countByExample(example);
    }

    //商品添加到劳保
    @Transactional
    public int addToLb(List<String> skuIdList) {
        ProductInfoExample example = new ProductInfoExample();
        example.createCriteria().andSkuIdIn(skuIdList);
        ProductInfo updateBean = new ProductInfo();
        updateBean.setIsLaobao(true);
        return productInfoMapper.updateByExampleSelective(updateBean, example);
    }

    //商品移除出劳保
    @Transactional
    public int removeFromLb(List<String> skuIdList) {
        ProductInfoExample example = new ProductInfoExample();
        example.createCriteria().andSkuIdIn(skuIdList);
        ProductInfo updateBean = new ProductInfo();
        updateBean.setIsLaobao(false);
        return productInfoMapper.updateByExampleSelective(updateBean, example);
    }

    //批量修改状态
    @Transactional
    public int updateStatusByIds(List<String> skuIdList,String status) {
        ProductInfoExample example = new ProductInfoExample();
        example.createCriteria().andSkuIdIn(skuIdList);
        ProductInfo updateBean = new ProductInfo();
        updateBean.setStatus(status);
        return productInfoMapper.updateByExampleSelective(updateBean, example);
    }

    //获取商品详情
    public JSONObject getProductDetail(String skuId) {
        JSONObject productDetail = new JSONObject();
        productDetail.put("skuId", skuId);
        Map<String, Object> imgMap = JDUtils.productSkuImage(skuId);
        if (!imgMap.isEmpty()) {
            JSONArray imgArr = ((JSONObject) imgMap.get("data")).getJSONArray(skuId);
            productDetail.put("imgArr", imgArr);
        }
        Map<String, Object> detailMap = JDUtils.productGetDetail(skuId, "wxintroduction");
        if (!detailMap.isEmpty()) {
            JSONObject detailJson = (JSONObject) detailMap.get("data");
            productDetail.put("name", detailJson.getString("name"));
            productDetail.put("saleUnit", detailJson.getString("saleUnit"));
            productDetail.put("wxintroduction", detailJson.getString("wxintroduction"));
        }
        Map<String, Object> priceMap = JDUtils.priceGetSellPrice(skuId);
        if (!priceMap.isEmpty()) {
            try {
                JSONObject priceJson = ((JSONArray) priceMap.get("data")).getJSONObject(0);
                productDetail.put("jdPrice", priceJson.getBigDecimal("jdPrice"));
            } catch (Exception e) {
                productDetail.put("jdPrice", "0");
            }
        }
        Map<String, Object> similarMap = JDUtils.productGetSimilarSku(skuId);
        if (!similarMap.isEmpty()) {
            JSONArray similarJson = (JSONArray) similarMap.get("data");
            for(int i=0;i<similarJson.size();i++) {
                JSONArray saleAttrList = similarJson.getJSONObject(i).getJSONArray("saleAttrList");
                Iterator<Object> o = saleAttrList.iterator();
                while (o.hasNext()) {
                    JSONObject jo = (JSONObject) o.next();
                    String skuIds = jo.getString("skuIds").replaceAll("\\[|\\]", "");
                    if(skuIds!=null && !"".equals(skuIds)) {
                    	 String[] split = skuIds.split(",");
                         String isdel ="0";
                         if(split.length>=1) {
                         	for (String string : split) {
                         		 ProductInfo selectByPrimaryKey = productInfoMapper.selectByPrimaryKey(skuIds);
                         		 if(selectByPrimaryKey !=null) {
                         			 isdel="1";
                         			 break;
                         		 }
                         		 
     						}
                         }
                         if("0".equals(isdel)) {
                             o.remove(); 
                         }
                    }
                   
                }
            }
            productDetail.put("similarSkus", similarJson);
        }
        return productDetail;
    }

    //根据skuId查询商品
    public ProductInfo getOneByPk(String skuId) {
        return productInfoMapper.selectByPrimaryKey(skuId);
    }

    private void saveProductInfo(ProductInfo productInfo,  String typeCode,String typeName) {
        productInfo.setTypeCode(typeCode);
        productInfo.setTypeName(typeName);
        productInfo.setIsdel("0");
        try {
            extProductInfoMapper.insertOrUpdateProduct(productInfo);
        } catch (Exception e) {
            log.error("商品保存失败，productInfo:{}", JSON.toJSONString(productInfo), e);
        }
    }

    private void getPrdListByType(String typeCode,String typeName) {
        try {
            int pageNum = 0;
            boolean loopFlag = true;
            while (loopFlag && pageNum < 100) {
                pageNum++;
                Map<String, Object> map = JDUtils.productGetSkuByPage(typeCode, pageNum);
                if (map.isEmpty()) {
                    return;
                }
                JSONObject data = (JSONObject) map.get("data");
                if (pageNum >= data.getIntValue("pageCount")) {
                    loopFlag = false;
                }
                List<Long> skuIds = JSONArray.parseArray(data.get("skuIds").toString(),Long.class);
//                List<Long> skuIds = (List<Long>)data.get("skuIds");
                //skuIds = skuIds.subList(0, 5);
                for (Long skuId : skuIds) {
                	JSONArray productCheck = JDUtils.productCheck(skuId.toString(), "");
                	if(productCheck != null ) {
                		for (int i = 0; i < productCheck.size(); i++) {
                			String saleState = productCheck.getJSONObject(i).getString("saleState");
                			if("1".equals(saleState)) {
                				 String sku = skuId.toString();
                				 Map<String, String> newStockById = JDUtils.getNewStockById(sku, "");
                				 if("有货".equals(newStockById.get("stockStateDesc"))) {
                					 Map<String, Object> prdMap = JDUtils.productGetDetail(sku, null);
                                     if (prdMap.isEmpty()) {
                                         continue;
                                     }
                                     Map<String, Object> priceMap = JDUtils.priceGetSellPrice(sku);
                                     if (priceMap.isEmpty()) {
                                         continue;
                                     }
                                     JSONObject prdJson = (JSONObject) prdMap.get("data");
                                     JSONArray priceJsonArr = (JSONArray) priceMap.get("data");
                                     if (priceJsonArr.size() < 1) {
                                         continue;
                                     }
                                     JSONObject priceJson = priceJsonArr.getJSONObject(0);
                                     ProductInfo item = new ProductInfo();
                                     item.setSkuId(sku);
                                     item.setName(prdJson.getString("name"));
                                     item.setImagePath(prdJson.getString("imagePath"));
                                     item.setBrand(prdJson.getString("brandName"));
                                     item.setJdPrice(priceJson.getBigDecimal("jdPrice"));
                                     item.setPrice(priceJson.getBigDecimal("price"));
                                     item.setRate(item.getPrice().divide(item.getJdPrice(), 2, RoundingMode.HALF_UP));
                                     item.setTypeCode(typeCode);
                                     item.setTypeName(typeName);
                                     item.setIsdel("0");
                                     ProductInfo selectByPrimaryKey = productInfoMapper.selectByPrimaryKey2(sku);
                                     if(selectByPrimaryKey !=null) {
                                    	 item.setStatus(selectByPrimaryKey.getStatus());
                                    	 item.setIsLaobao(selectByPrimaryKey.getIsLaobao());
                                    	 item.setCreateDatetime(selectByPrimaryKey.getCreateDatetime());
                                    	 item.setUpdateDatetime(new Date());
                                    	 productInfoMapper.updateByPrimaryKey(item);
                                     }else {
                                    	 item.setStatus(StatusEnum.ON.getCode());
                                    	 item.setIsLaobao(false);
                                    	 item.setCreateDatetime(new Date());
                                    	 item.setUpdateDatetime(new Date());
                                    	 productInfoMapper.insert(item);
                                     } 
                				 }
                			}
						}
                	}
                }
            }
        } catch (Exception e) {
            log.error("按类型查询商品列表失败，typeCode:{}", typeCode, e);
        }
    }

    private ProductInfoExample buildPageExmple(ProductInfoDto reqDto) {
        ProductInfoExample example = new ProductInfoExample();
        ProductInfoExample.Criteria criteria = example.createCriteria();
        if (null != reqDto.getMinPrice()) {
            criteria.andJdPriceGreaterThanOrEqualTo(reqDto.getMinPrice());
        }
        if (null != reqDto.getMaxPrice()) {
            criteria.andJdPriceLessThanOrEqualTo(reqDto.getMaxPrice());
        }
        if (null != reqDto.getSkuId()) {
            criteria.andSkuIdEqualTo(reqDto.getSkuId());
        }
        if (null != reqDto.getIsLaobao()) {
            criteria.andIsLaobaoEqualTo(reqDto.getIsLaobao());
        }
        if (StrUtil.isNotBlank(reqDto.getTypeCode())) {
            criteria.andTypeCodeEqualTo(reqDto.getTypeCode());
        }
        if (StrUtil.isNotBlank(reqDto.getNameWord())) {
            criteria.andNameLike("%" + reqDto.getNameWord() + "%");
        }
        if (StrUtil.isNotBlank(reqDto.getStatus())) {
            criteria.andStatusEqualTo(reqDto.getStatus());
        }
        criteria.andIsdelEqualTo("0");
        return example;
    }
}
